package pl.kosmowska.ewelina.client.views.impl;

import java.util.Date;
import java.util.List;

import pl.kosmowska.ewelina.client.ViewMessages;
import pl.kosmowska.ewelina.client.app.requestfactory.dto.LoanDataProxy;
import pl.kosmowska.ewelina.client.views.LoanEditView;
import pl.kosmowska.ewelina.client.views.impl.beans.Installment;
import pl.kosmowska.ewelina.client.views.widgets.MessageDialogBox;
import pl.kosmowska.ewelina.client.views.widgets.grids.InstallmentGrid;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ResizeLayoutPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.PieChart;
import com.google.gwt.visualization.client.visualizations.PieChart.Options;

public class LoanEditViewImpl extends Composite implements LoanEditView{

	private static LoanEditViewImplUiBinder uiBinder = GWT
			.create(LoanEditViewImplUiBinder.class);
	@UiField Button confirmButton;
	@UiField Button clearButton;
	@UiField HorizontalPanel datePanel;
	@UiField TextBox nameBox;
	@UiField DoubleBox valueBox;
	@UiField DoubleBox percentageBox;
	@UiField DoubleBox feeBox;
	@UiField DoubleBox otherPaymentsBox;
	@UiField ListBox feeChoiceBox;
	@UiField ListBox installmentChoiceBox;
	@UiField IntegerBox monthNumberBox;
	@UiField VerticalPanel summaryPanel;
	@UiField Label clientCapitalLabel;
	@UiField Label loanCapitalLabel;
	@UiField Label feeLabel;
	@UiField Label totalLoanLabel;
	@UiField Label otherPaymentsLabel;
	@UiField ResizeLayoutPanel installmentPanel;
	@UiField ResizeLayoutPanel chartPanel;
	@UiField HorizontalPanel feePanel;
	@UiField HorizontalPanel finalButtonPanel;

	private InstallmentGrid<Installment> installmentGrid;

	DateBox startDateBox;

	private Presenter presenter;
	private boolean alreadyInit;
	private LoanDataProxy loanData;


	interface LoanEditViewImplUiBinder extends UiBinder<Widget, LoanEditViewImpl> {
	}

	public LoanEditViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));
		datePanel.add(initStartDateBox());
		initInstallmentChoiceBox();
		initFeeChoiceBox();
	}

	@Override
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}

	@Override
	public void reInitView() {
		summaryPanel.setVisible(false);
		feePanel.setVisible(false);
		installmentPanel.setVisible(false);
		if(loanData!=null){
			fillForm();
		}else{
			clearForm();
		}
	}

	private void clearForm() {
		nameBox.setText(null);
		valueBox.setValue(null);
		percentageBox.setValue(null);
		feeBox.setValue(null);
		feeBox.setEnabled(false);
		startDateBox.setValue(null);
		monthNumberBox.setValue(null);
		otherPaymentsBox.setValue(null);

	}

	private void initInstallmentChoiceBox() {
		installmentChoiceBox.addItem("Raty równe");
		installmentChoiceBox.addItem("Raty malejące");
	}

	private void initFeeChoiceBox() {
		feeChoiceBox.addItem("Nie uwzgledniaj");
		feeChoiceBox.addItem("Powieksza kwote kredytu");
		feeChoiceBox.addItem("Pomniejsz kwote wypłaty");
		feeChoiceBox.addItem("Opłacona osobno");
	}


	public void setData(LoanDataProxy loanData) {
		this.loanData = loanData;
	}

	private void fillForm() {
		nameBox.setText(loanData.getName());
		valueBox.setValue((double)loanData.getValue());
		percentageBox.setValue((double)loanData.getPercentage());
		feeChoiceBox.setSelectedIndex(loanData.getFeeChoice());
		if(loanData.getFeeChoice()!=0)
			feeBox.setValue((double)loanData.getFee());
		else
			feeBox.setEnabled(false);
		startDateBox.setValue(loanData.getStartDate());
		installmentChoiceBox.setSelectedIndex(loanData.getInstallmentChoice());
		feeChoiceBox.setSelectedIndex(loanData.getFeeChoice());
		monthNumberBox.setValue(loanData.getMonthNumber());
		otherPaymentsBox.setValue((double)loanData.getOtherPayments());
	}

	public HorizontalPanel initStartDateBox(){
		// Create a DateBox
		DateTimeFormat dateFormat = DateTimeFormat.getLongDateFormat();
		startDateBox = new DateBox();
		startDateBox.setFormat(new DateBox.DefaultFormat(dateFormat));

		// Combine the widgets into a panel and return them
		HorizontalPanel vPanel = new HorizontalPanel();
		vPanel.add(new HTML("Data pierwszej raty: "));
		vPanel.add(startDateBox);
		return vPanel;
	}


	@UiHandler("clearButton")
	void onClearButtonClick(ClickEvent event) {
		clearForm();
	}
	@UiHandler("returnButton")
	void onReturnButtonClick(ClickEvent event) {
		presenter.goToLoanPlace();
	}
	@UiHandler("calculateButton")
	void onCalculateButtonClick(ClickEvent event) {
		if(validateForm()){
			String name =nameBox.getText();
			float value = valueBox.getValue().floatValue();
			float percentage= percentageBox.getValue().floatValue();
			Date startDate =startDateBox.getValue();
			int feeChoice= feeChoiceBox.getSelectedIndex();
			float fee=0;
			if(feeChoice!=0)
				fee = feeBox.getValue().floatValue();
			int installmentChoice=installmentChoiceBox.getSelectedIndex();
			int monthNumber=monthNumberBox.getValue();
			float otherPayments=otherPaymentsBox.getValue().floatValue();

			presenter.generateLoan(name,value,percentage,startDate,feeChoice,fee,installmentChoice,monthNumber,otherPayments);

		}else{
			showMessage(ViewMessages.ERROR_WRONG_INPUT);
		}

	}

	private boolean validateForm() {
		if(validate(nameBox)&& validate(valueBox)&& validate(percentageBox)&&validate(startDateBox)&&validate(monthNumberBox)&&validate(otherPaymentsBox)){
			return true;
		}else{
			return false;
		}
	}

	private boolean validate(IntegerBox integerBox) {
		if(integerBox.getValue()==null)
			return false;
		else
			return true;
	}

	private boolean validate(DateBox dateBox) {
		if(dateBox.getValue()==null)
			return false;
		else
			return true;
	}

	private boolean validate(DoubleBox doubleBox) {
		if(doubleBox.getValue()==null)
			return false;
		else
			return true;
	}

	private boolean validate(TextBox textbox) {
		if(textbox.getText()==null || textbox.getText().equals("") )
			return false;
		else
			return true;
	}
	@Override
	public void loadChart(final float clientCapital, final float interestAmount, final float feePayment){

		Runnable onLoadCallback = new Runnable() {
			public void run() {
				PieChart pie = new PieChart(createTable(clientCapital,interestAmount, feePayment ), createOptions());
				chartPanel.setWidget(pie);
			}
		};
		VisualizationUtils.loadVisualizationApi(onLoadCallback, PieChart.PACKAGE);
	}

	private Options createOptions() {
		Options options = Options.create();
		options.setWidth(400);
		options.setHeight(240);
		options.set3D(true);
		options.setTitle("Calkowita kwota kredytu");
		return options;
	}

	private AbstractDataTable createTable(float clientCapital, float interestAmount, float feePayment) {
		DataTable data = DataTable.create();
		data.addColumn(ColumnType.STRING, "Dział");
		data.addColumn(ColumnType.NUMBER, "Wartość");
		data.addRows(3);
		data.setValue(0, 0, "Kapitał klienta");
		data.setValue(0, 1, round(clientCapital));
		data.setValue(1, 0, "Odsetki");
		data.setValue(1, 1, round(interestAmount));
		data.setValue(2, 0, "Prowizja");
		data.setValue(2, 1, round(feePayment));
		return data;
	}


	@Override
	public void showGrid(List<Installment> installmentList){
		installmentPanel.clear();
		installmentPanel.setVisible(true);
		installmentGrid = new InstallmentGrid<Installment>();
		installmentGrid.setHeight("600px");
		installmentGrid.setDataList(installmentList);	
		installmentPanel.add(installmentGrid);
	}

	@Override
	public void showSummary(float clientCapital, float loanCapital, float feePayment, float otherPayments, float totalAmount) {
		summaryPanel.setVisible(true);
		clientCapitalLabel.setText(String.valueOf(clientCapital));
		loanCapitalLabel.setText(String.valueOf(loanCapital));
		feeLabel.setText(String.valueOf(feePayment));
		otherPaymentsLabel.setText(String.valueOf(otherPayments));
		totalLoanLabel.setText(String.valueOf(round(totalAmount)));
		finalButtonPanel.setVisible(true);
	}

	@UiHandler("confirmButton")
	void onConfirmButtonClick(ClickEvent event) {	    
		presenter.saveLoanData();
	}

	private double round (double val)
	{
		double exp = Math.pow(10, 2);
		double rounded = val * exp;
		rounded = Math.round(rounded);
		return rounded / exp;
	}

	@UiHandler("feeChoiceBox")
	void onFeeChoiceBoxClick(ClickEvent event) {
		if(feeChoiceBox.getSelectedIndex()!=0){
			feePanel.setVisible(true);
			feeBox.setEnabled(true);
		}else
			feePanel.setVisible(false);
	}
	@Override
	public void showMessage(String errorMessage) {
		MessageDialogBox messageDialogBox = new MessageDialogBox(errorMessage);
		messageDialogBox.center();
		messageDialogBox.show();

	}
	@Override
	public boolean isAlreadyInit() {
		return alreadyInit;
	}
	@Override
	public void setAlreadyInit(boolean alreadyInit) {
		this.alreadyInit = alreadyInit;
	}
}
